package com.sign2024.sign2024project.projectservice.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sign2024.sign2024core.common.constants.CommonConstants;
import com.sign2024.sign2024core.common.exeception.CommonException;
import com.sign2024.sign2024core.common.utils.StringUtils;
import com.sign2024.sign2024core.entry.projectservice.GcProgect;
import com.sign2024.sign2024core.entry.projectservice.SpecialtySignRelation;
import com.sign2024.sign2024core.entry.projecttask.ProjectTask;
import com.sign2024.sign2024project.aop.dealUtils.DealClassUtils;
import com.sign2024.sign2024project.projectservice.mapper.*;
import com.sign2024.sign2024project.projectservice.param.BatchNeedParam;
import com.sign2024.sign2024project.projectservice.service.GcProgectService;
import com.sign2024.sign2024project.projectservice.vo.GCProgectVo;
import com.sign2024.sign2024project.projecttask.mapper.ProjectTaskMapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 工程服务抽取方案
 *
 * @author yujie
 * @data 2024/8/26 11:19
 */
@Service
public class GcProgectServiceImpl implements GcProgectService {

    @Resource
    private GcProgectMapper gcProgectMapper;

    // 本批需求一览表
    @Resource
    private BatchNeedMapper batchNeedMapper;

    // 计划清单
    @Resource
    private PlanInventoryMapper planInventoryMapper;

    // 记录汇总
    @Resource
    private RecordCollectMapper recordCollectMapper;

    // 专家专业与标段对应关系
    @Resource
    private SpecialtySignRelationMapper specialtySignRelationMapper;

    // 专家信息
    @Resource
    private SpecialistInfoMapper specialistInfoMapper;

    // 任务
    @Resource
    private ProjectTaskMapper projectTaskMapper;

//    @Override
//    public void processingGcDate(Integer taskId) {
//        // 1. 获取分标名称列表
//        List<GCProgectVo> gcProgectVos = planInventoryMapper.selectSignName(taskId);
//        // 根据 分标名称 匹配出 epc2.0 标段类型
////        List<GCProgectVo> gcProgectVos = planInventoryMapper.selectDistinctGCData(taskId);
//        // 根据 分标名称 筛选出的 最大金额下的项目名称 列表的做大 一条
//        // 处理金额 最大 根据 分标名称 分标名称下金额最大  物料编码
//        // 分标名称 找多少个部门 写到一起
//        // 处理分包数量  根据 分标名称 筛选出  分包数量(去重)
//        // 根据 分标名称 查询有对少个公司  家次 不去重  家数 去重
//        // 根据 物料编码 匹配 专家专业
//        // 根据 技术专家专业进行匹配 商务直接写死 为 商务总和
//        if (StringUtils.isNotEmpty(gcProgectVos)) {
//            // 首先 过滤掉 无用数据
//            List<GCProgectVo> filteredGcProgectVos = gcProgectVos.stream()
//                    .map(gc -> {
//                        // 根据 分标名称 匹配出 epc2.0 标段类型
//                        GCProgectVo epcTwoAndType = batchNeedMapper.selectEpcTwoAndType(taskId, gc.getSignName());
//                        if (epcTwoAndType != null) {
//                            gc.setEpcTwo(epcTwoAndType.getEpcTwo());
//                            gc.setSignType(epcTwoAndType.getSignType());
//                            return gc; // 返回有效数据
//                        } else {
//                            // TODO 暂时先注释掉(便于测试) 返回null 排除数据
//                            return null;
//                        }
//                    })
//                    .filter(gc -> gc != null) // 过滤掉为 null 的条目
//                    .collect(Collectors.toList()); // 收集结果
//
//            // 更新原始列表
//            gcProgectVos.clear();
//            gcProgectVos.addAll(filteredGcProgectVos);
//
//            for (GCProgectVo gc : gcProgectVos) {
//                // 分标名称 找多少个部门 写到一起(进行部门的合并)
//                List<String> comDepaList = planInventoryMapper.selectComDepa(taskId, gc.getSignName());
//                // 处理 部分 合并
//                gc.setComDepa(joinStrings(comDepaList));
//
//                // 处理分包数量
//                int num = batchNeedMapper.countKindNameNum(taskId, gc.getSignName());
//                gc.setKindNameNum(num);
//
//                // 家次 不去重
//                int familyNext = recordCollectMapper.countFamilyNext(taskId, gc.getEpcTwo());
//                gc.setFamilyNext(familyNext);
//
//                // 家数 去重
//                int familyNumber = recordCollectMapper.countFamilyNumber(taskId, gc.getEpcTwo());
//                gc.setFamilyNumber(familyNumber);
//
////                // 标名称下金额最大  物料编码
////                GCProgectVo maxSignMoney =
////                        planInventoryMapper.maxSignMoney(taskId, gc.getSignName());
////                if (StringUtils.isNotNull(maxSignMoney)) {
////                    // 将数据进行赋值
////                    // 最大金额
////                    gc.setMaxSignMoney(maxSignMoney.getMaxSignMoney());
////                    // 物料+编码
////                    gc.setSuppliesCode(maxSignMoney.getSuppliesCode());
//////                    // 金额最大的项目名称
////                    gc.setProjectName(maxSignMoney.getProjectName());
////                }
//
////                // 根据 物料编码 匹配 专家专业
////                SpecialtySignRelation relation =
////                        specialtySignRelationMapper.selectRelationByCode(gc.getSuppliesCode());
////
////                if (relation != null) {
////                    // 进行 四级匹配 先匹配 专家专业1 如果1为空， 找专家专业2 一次类推
////                    if (StringUtils.isNotNull(relation.getSignMajorOne())) {
////                        // 专家专业1 不为空
////                        gc.setSignMajor(relation.getSignMajorOne());
////                    } else if (StringUtils.isNull(relation.getSignMajorOne())
////                            && StringUtils.isNotNull(relation.getSignMajorTwo())) {
////                        // 如果 专家专业1 为空 专家专业2 不为空 选取 专家专业2 的数据
////                        gc.setSignMajor(relation.getSignMajorTwo());
////                    } else if (StringUtils.isNull(relation.getSignMajorOne())
////                            && StringUtils.isNull(relation.getSignMajorTwo())
////                            && StringUtils.isNotNull(relation.getSignMajorThree())) {
////                        // 如果 专家专业1,2  为空 专家专业3 不为空 选取 专家专业3 的数据
////                        gc.setSignMajor(relation.getSignMajorThree());
////                    } else if (StringUtils.isNull(relation.getSignMajorOne())
////                            && StringUtils.isNull(relation.getSignMajorTwo())
////                            && StringUtils.isNull(relation.getSignMajorThree())
////                            && StringUtils.isNotNull(relation.getSignMajorFour())) {
////                        // 如果 专家专业1,2,3  为空 专家专业4 不为空 选取 专家专业4 的数据
////                        gc.setSignMajor(relation.getSignMajorFour());
////                    }
////                }
//
//                // 修改 这里 的逻辑 获取 金额大于30% 的 物料编码
//                List<String> codeList = new ArrayList<>();
//                List<String> greaterThanList =
//                        planInventoryMapper.selectGreaterThanSignMoney(taskId, gc.getSignName());
//                if (greaterThanList.isEmpty()) {
//                    // 获取 前三个 物料编码
//                    List<String> threeList =
//                            planInventoryMapper.selectThreeSignMoney(taskId, gc.getSignName());
//                    if (!threeList.isEmpty()) {
//                        codeList.addAll(threeList);
//                    }
//                } else {
//                    codeList.addAll(greaterThanList);
//                }
//
//                // 物料编码 不为空 匹配 专业
//                if (!codeList.isEmpty()) {
//                    List<String> tempStr = new ArrayList<>();
//                    for (String code : codeList) {
//                        // 根据 物料编码 匹配 专家专业
//                        SpecialtySignRelation relation =
//                                specialtySignRelationMapper.selectRelationByCode(code);
//                        if (relation != null) {
//                            // 进行 四级匹配 先匹配 专家专业1 如果1为空， 找专家专业2 一次类推
//                            if (StringUtils.isNotNull(relation.getSignMajorOne())) {
//                                tempStr.add(relation.getSignMajorOne());
//                            } else if (StringUtils.isNull(relation.getSignMajorOne())
//                                    && StringUtils.isNotNull(relation.getSignMajorTwo())) {
//                                tempStr.add(relation.getSignMajorTwo());
//                            } else if (StringUtils.isNull(relation.getSignMajorOne())
//                                    && StringUtils.isNull(relation.getSignMajorTwo())
//                                    && StringUtils.isNotNull(relation.getSignMajorThree())) {
//                                tempStr.add(relation.getSignMajorThree());
//                            } else if (StringUtils.isNull(relation.getSignMajorOne())
//                                    && StringUtils.isNull(relation.getSignMajorTwo())
//                                    && StringUtils.isNull(relation.getSignMajorThree())
//                                    && StringUtils.isNotNull(relation.getSignMajorFour())) {
//                                tempStr.add(relation.getSignMajorFour());
//                            }
//                        }
//                    }
//
//                    // 将 专业 拼接 到 一起
//                    if (!tempStr.isEmpty()) {
//                        // 使用LinkedHashSet去重并保持原始顺序
//                        Set<String> set = new LinkedHashSet<>(tempStr);
//                        List<String> uniqueList = new ArrayList<>(set);
//                        gc.setSignMajor(joinStrings(uniqueList));
//                    }
//                }
//            }
//        }
//        // 先 排序
//        gcProgectVos.sort(Comparator.comparing(GCProgectVo::getSignType, Comparator.nullsLast(Comparator.naturalOrder())));
//
//        // 是否知道是那个类
//        // 将根据 signType 字段分组
//        Map<String, List<GCProgectVo>> groupedBySignType = gcProgectVos.stream()
//                .collect(Collectors.groupingBy(GCProgectVo::getSignType));
//        // 将分组结果转换为 List<List<GCProgectVo>>
//        List<List<GCProgectVo>> result = new ArrayList<>(groupedBySignType.values());
//
//        // 获取 任务公式 信息
//        ProjectTask projectTask = projectTaskMapper.selectById(taskId);
//        // 技术评标量(家数/家次)
//        String skillFamily = projectTask.getSkillFamily();
//
//        // 技术分组
//        // 创建 map 存储数据 标段类型 类型下计算出的总人数
//        Map<String, Integer> typeMap = new HashMap<>();
//
//        // 计算出 每个类型所需 总人数
//        if (StringUtils.isNotEmpty(result)) {
//            for (List<GCProgectVo> list : result) {
//                int skillTotalPerson = 0;
//                // 判断是家数还是家次
//                if (skillFamily.equals("家数")) {
//                    int totalFamilyNumber = list.stream()
//                            .mapToInt(GCProgectVo::getFamilyNumber)
//                            .sum();
//                    // 向上取整 Math.ceil()
//                    double v = Double.valueOf(totalFamilyNumber) / projectTask.getSkillSignNum();
//                    skillTotalPerson = (int) Math.ceil(v);
//                } else {
//                    // 计算 familyNext 的总和
//                    int totalFamilyNext = list.stream()
//                            .mapToInt(GCProgectVo::getFamilyNext)
//                            .sum();
//                    double v = Double.valueOf(totalFamilyNext) / projectTask.getSkillSignNum();
//                    skillTotalPerson = (int) Math.ceil(v);
//                }
//                typeMap.put(list.get(0).getSignType(), skillTotalPerson);
//            }
//        }
//
//
//        // 直接去存储数据
//        Map<String, List<GCProgectVo>> tempMap = new HashMap<>();
//        for (int i = 0; i < result.size(); i++) {
//            // 存储有几列数据
//            List<Integer> recordNum = new ArrayList<>();
//            // 获取 该 list 中的 标段类型
//            String signType = result.get(i).get(0).getSignType();
//            // 根据类型 获取 该类型所需总人数
//            Integer integer = typeMap.get(signType);
//
////            // 排序 标段类型 以及家数/家次
////            result.get(i).sort((vo1, vo2) -> {
////                // 按照 SignType 进行排序
////                int signTypeComparison = Comparator
////                        .comparing(GCProgectVo::getSignType, Comparator.nullsLast(Comparator.naturalOrder()))
////                        .compare(vo1, vo2);
////
////                if (signTypeComparison != 0) {
////                    return signTypeComparison;
////                }
////
////                // 判断 skillFamily 的值来决定后续排序
////                if ("家数".equals(skillFamily)) {
////                    return Comparator
////                            .comparing(GCProgectVo::getFamilyNumber, Comparator.nullsLast(Comparator.reverseOrder()))
////                            .compare(vo1, vo2);
////                } else {
////                    return Comparator
////                            .comparing(GCProgectVo::getFamilyNext, Comparator.nullsLast(Comparator.reverseOrder()))
////                            .compare(vo1, vo2);
////                }
////            });
//
//            // 获取 该类型 下小组数 以及人员数
//            List<Integer> classNumList =
//                    DealClassUtils.dealGcClassNum(integer, projectTask.getSkillStart(), projectTask.getSkillEnd());
//
//            // 判断 有几个小组
//            if (classNumList.size() == 1) {
//                // 小组人数为 1 直接赋值
//                // 存储数据
//                List<GCProgectVo> oneList = new ArrayList<>();
//                for (int j = 0; j < result.get(i).size(); j++) {
//                    result.get(i).get(j).setSkillTotalNum(classNumList.get(0));
//                    oneList.add(result.get(i).get(j));
//                }
////                String className = "技术" + (tempMap.size() + 1) + "组";
//                String className = "技术" + convertToChinese(tempMap.size() + 1) + "组";
//                tempMap.put(className, oneList);
//            } else if (classNumList.size() == 2) {
//                // 为两组 分出一组 即可， 剩下即为一组
//                List<GCProgectVo> oneList = new ArrayList<>();
//                List<GCProgectVo> twoList = new ArrayList<>();
//
//                // 该小组 预计总评标量
//                Integer skillSignNum = projectTask.getSkillSignNum() * classNumList.get(0);
//                // 当前次 的总和
//                int total = 0;
//                // 下一次数据总和
//                int nextValue = 0;
//                //  遍历 集合计算 列表中的评标量
//                for (int j = 0; j < result.get(i).size(); ) {
//                    // 判断是家数还是家次
//                    if (skillFamily.equals("家数")) {
//                        total += result.get(i).get(j).getFamilyNumber();
//                    } else {
//                        total += result.get(i).get(j).getFamilyNext();
//                    }
//
//                    if (total <= skillSignNum) {
//                        // 向map中添加数据值
//                        result.get(i).get(j).setSkillTotalNum(classNumList.get(0));
//                        oneList.add(result.get(i).get(j));
//                        result.get(i).remove(j);
//                    } else {
//                        // 不满足 结束循环，避免其 无限循环
//                        break;
//                    }
//                    nextValue += 1;
//                    if (nextValue > result.get(i).size()) {
//                        // 数据标记，避免无限循环
//                        break;
//                    }
//                }
//
//                String className = "技术" + convertToChinese(tempMap.size() + 1) + "组";
//                tempMap.put(className, oneList);
//
//                for (int j = 0; j < result.get(i).size(); j++) {
//                    result.get(i).get(j).setSkillTotalNum(classNumList.get(1));
//                    twoList.add(result.get(i).get(j));
//                }
//                String className2 = "技术" + convertToChinese(tempMap.size() + 1) + "组";
//                tempMap.put(className2, twoList);
//            } else if (classNumList.size() > 2) {
//                // 这里 是3组 及以上
//                // 循环小组
//                for (int j = 0; j < classNumList.size(); j++) {
//                    if (j == classNumList.size() - 1) {
//                        // 最后一次循环直接处理数据
//                        List<GCProgectVo> oneList = new ArrayList<>();
//                        if (!result.get(i).isEmpty()) {
//                            for (int k = 0; k < result.get(i).size(); k++) {
//                                result.get(i).get(k).setSkillTotalNum(classNumList.get(j));
//                                oneList.add(result.get(i).get(k));
//                            }
//                            String className = "技术" + convertToChinese(tempMap.size() + 1) + "组";
//                            tempMap.put(className, oneList);
//                        }
//                    } else {
//                        List<GCProgectVo> oneList = new ArrayList<>();
//                        // 该小组 预计总评标量
//                        Integer skillSignNum = projectTask.getSkillSignNum() * classNumList.get(j);
//                        int total = 0;
//                        // 下一次数据总和
//                        int nextValue = 0;
//                        //  遍历 集合计算 列表中的评标量
//                        for (int k = 0; k < result.get(i).size(); ) {
//                            // 判断是家数还是家次
//                            if (skillFamily.equals("家数")) {
//                                total += result.get(i).get(k).getFamilyNumber();
//                            } else {
//                                total += result.get(i).get(k).getFamilyNext();
//                            }
//
//                            if (total <= skillSignNum) {
//                                // 向map中添加数据值
//                                result.get(i).get(k).setSkillTotalNum(classNumList.get(j));
//                                oneList.add(result.get(i).get(k));
//                                result.get(i).remove(k);
//                            } else {
//                                // 不满足 重新记录数据
//                                break;
//                            }
//
//                            nextValue += 1;
//                            if (nextValue > result.get(i).size()) {
//                                // 数据标记，避免无限循环
//                                break;
//                            }
//                        }
//                        // 获取组名
//                        String className = "技术" + convertToChinese(tempMap.size() + 1) + "组";
//                        tempMap.put(className, oneList);
//                    }
//                }
//            }
//        }
//
////        List<GCProgectVo> vos = new ArrayList<>();
////        for (int i = 0; i < tempMap.size(); i++) {
//////            String keyName = "技术" + (i + 1) + "组";
////            String keyName = "技术" + convertToChinese(i + 1) + "组";
////            List<GCProgectVo> voList = tempMap.get(keyName);
////            // 获取该小组 总人数
////            Integer skillTotalNum = voList.get(0).getSkillTotalNum();
////            // 分配异地人数
////            //  （技术专家总人数+1）÷3（向上取整）
////            double v = Double.valueOf((skillTotalNum + 1)) / projectTask.getOtherSkill();
////            int skillOtherNum = (int) Math.ceil(v);
////            // 最后必须确保 本地 人数 大于 projectTask.getOtherLocal() (本地保留人数)
////            // 求 集合总数
////            int totalFamily = 0;
////            if (skillFamily.equals("家数")) {
////                totalFamily = voList.stream()
////                        .mapToInt(GCProgectVo::getFamilyNumber)
////                        .sum();
////            } else {
////                // 计算 familyNext 的总和
////                totalFamily = voList.stream()
////                        .mapToInt(GCProgectVo::getFamilyNext)
////                        .sum();
////            }
////
////
////            int count = skillTotalNum;
////            for (GCProgectVo gc : voList) {
////                // 遍历集合 求占比
////                int temp = 0;
////                if (skillFamily.equals("家数")) {
////                    temp = gc.getFamilyNumber();
////                } else {
////                    // 计算 familyNext 的总和
////                    temp = gc.getFamilyNext();
////                }
////
////                // 计算占比
////                double proportion = (double) temp / totalFamily;
////                // 向上取整 Math.ceil()
////                int personNum = (int) Math.ceil(proportion * skillTotalNum);
////
////                if (count - personNum < 0) {
////                    personNum = count;  // 分配剩余的全部
////                }
////
////                // 更新count值
////                count -= personNum;
////
////                // 只在count大于0时进行赋值操作
////                if (count >= 0) {
////                    if (personNum > 0) {
////                        gc.setSkillMajorNum(personNum);
////                    }
////                }
////                // 异地人数
////                gc.setSkillOtherNum(skillOtherNum);
////                // 分组
////                gc.setSkillClass(keyName);
////                vos.add(gc);
////            }
////        }
//
//
//        List<GCProgectVo> vos = new ArrayList<>();
//        for (int i = 0; i < tempMap.size(); i++) {
//            String keyName = "技术" + convertToChinese(i + 1) + "组";
//            List<GCProgectVo> voList = tempMap.get(keyName);
//            // 获取该小组 总人数
//            Integer skillTotalNum = voList.get(0).getSkillTotalNum();
//            // 分配异地人数
//            //  （技术专家总人数+1）÷3（向上取整）
//            double v = Double.valueOf((skillTotalNum + 1)) / projectTask.getOtherSkill();
//            int skillOtherNum = (int) Math.ceil(v);
//            // 最后必须确保 本地 人数 大于 projectTask.getOtherLocal() (本地保留人数)
//            // 求 集合总数
//            int totalFamily = 0;
//            if (skillFamily.equals("家数")) {
//                totalFamily = voList.stream()
//                        .mapToInt(GCProgectVo::getFamilyNumber)
//                        .sum();
//            } else {
//                // 计算 familyNext 的总和
//                totalFamily = voList.stream()
//                        .mapToInt(GCProgectVo::getFamilyNext)
//                        .sum();
//            }
//
//
//            int count = skillTotalNum;
//            for (GCProgectVo gc : voList) {
//                // 遍历集合 求占比
//                int temp = 0;
//                if (skillFamily.equals("家数")) {
//                    temp = gc.getFamilyNumber();
//                } else {
//                    // 计算 familyNext 的总和
//                    temp = gc.getFamilyNext();
//                }
//
//                // 计算占比
//                double proportion = (double) temp / totalFamily;
//                // 向上取整 Math.ceil()
//                int personNum = (int) Math.ceil(proportion * skillTotalNum);
//
//                if (count - personNum < 0) {
//                    personNum = count;  // 分配剩余的全部
//                }
//
//                count -= personNum;
//
////                if (count >= 0) {
////                    if (personNum > 0) {
//////                        gc.setSkillMajorNum(personNum);
////                        // 暂 改为 字符串
////                        gc.setSkillMajorNum(String.valueOf(personNum));
////
////                        // 判断 人数 是否 满足 获取专业 人数
////                        List<SpecialistInfo> infoList = specialistInfoMapper.selectInfoByMajorName(gc.getSignMajor());
////                        if (infoList.size() < personNum) {
////                            // 如果 小于 修改 专业
////                            // 获取技术专家专业
////                            SpecialtySignRelation relation =
////                                    specialtySignRelationMapper.selectRelationByCode(gc.getSuppliesCode());
////
////                            // 获取 当前 技术专业
////                            String signMajor = gc.getSignMajor();
////                            if (StringUtils.isNotNull(signMajor)) {
////                                // 判断 其不为 空
////                                // 技术专业 四级 匹配
////                                // 判断当前 专业 使用的是 哪一个字段  signMajorOne signMajorTwo signMajorThree signMajorFour
////                                // 如果 其 使用的 是 signMajorOne
////                                if (signMajor.equals(relation.getSignMajorOne())) {
////                                    // 首先 判断 其 2 是否为空 如果 为 空 不做任何处理
////                                    if (StringUtils.isNotNull(relation.getSignMajorTwo())) {
////                                        // 不为空 做 数据处理
////                                        List<SpecialistInfo> twoList
////                                                = specialistInfoMapper.selectInfoByMajorName(relation.getSignMajorTwo());
////                                        // 判断 人数
////                                        if (twoList.size() < personNum) {
////                                            // 不满足 条件  继续 上面 判断 处理
////                                            // 判断 3 是否为空 为空不做任何处理
////                                            if (StringUtils.isNotNull(relation.getSignMajorThree())) {
////                                                List<SpecialistInfo> threeList
////                                                        = specialistInfoMapper.selectInfoByMajorName(relation.getSignMajorThree());
////
////                                                // 判断 人数
////                                                if (threeList.size() < personNum) {
////                                                    // 不满足 继续 逻辑处理
////                                                    // 判断 4 是否 为空
////                                                    if (StringUtils.isNotNull(relation.getSignMajorFour())) {
////                                                        List<SpecialistInfo> fourList
////                                                                = specialistInfoMapper.selectInfoByMajorName(relation.getSignMajorFour());
////                                                        // 判断 人数
////                                                        if (fourList.size() < personNum) {
////                                                            // 最后 仍然 不满足 如何做数据处理
////                                                            // 人数上显示 除 人数不足
////                                                            String personStr = personNum + "(该专业人数不足)";
////                                                            gc.setSkillMajorNum(personStr);
////                                                            gc.setSignMajor(relation.getSignMajorFour());
////
////                                                        } else {
////                                                            gc.setSignMajor(relation.getSignMajorFour());
////                                                        }
////                                                    }
////                                                } else {
////                                                    gc.setSignMajor(relation.getSignMajorThree());
////                                                }
////                                            }
////
////                                        } else {
////                                            // 满足 技术专家专业 进行赋值
////                                            gc.setSignMajor(relation.getSignMajorTwo());
////                                        }
////                                    }
////                                } else {
////                                    // 2
////                                    if (signMajor.equals(relation.getSignMajorTwo())) {
////                                        // 判断 3 是否为空 为空不做任何处理
////                                        if (StringUtils.isNotNull(relation.getSignMajorThree())) {
////                                            List<SpecialistInfo> threeList
////                                                    = specialistInfoMapper.selectInfoByMajorName(relation.getSignMajorThree());
////
////                                            // 判断 人数
////                                            if (threeList.size() < personNum) {
////                                                // 不满足 继续 逻辑处理
////                                                // 判断 4 是否 为空
////                                                if (StringUtils.isNotNull(relation.getSignMajorFour())) {
////                                                    List<SpecialistInfo> fourList
////                                                            = specialistInfoMapper.selectInfoByMajorName(relation.getSignMajorFour());
////                                                    // 判断 人数
////                                                    if (fourList.size() < personNum) {
////                                                        // 最后 仍然 不满足 如何做数据处理
////                                                        // 人数上显示 除 人数不足
////                                                        String personStr = personNum + "(该专业人数不足)";
////                                                        gc.setSkillMajorNum(personStr);
////                                                        gc.setSignMajor(relation.getSignMajorFour());
////
////                                                    } else {
////                                                        gc.setSignMajor(relation.getSignMajorFour());
////                                                    }
////                                                }
////                                            } else {
////                                                gc.setSignMajor(relation.getSignMajorThree());
////                                            }
////                                        }
////                                    } else {
////                                        // 3
////                                        if (signMajor.equals(relation.getSignMajorThree())) {
////                                            if (StringUtils.isNotNull(relation.getSignMajorFour())) {
////                                                List<SpecialistInfo> fourList
////                                                        = specialistInfoMapper.selectInfoByMajorName(relation.getSignMajorFour());
////                                                // 判断 人数
////                                                if (fourList.size() < personNum) {
////                                                    // 最后 仍然 不满足 如何做数据处理
////                                                    // 人数上显示 除 人数不足
////                                                    String personStr = personNum + "(该专业人数不足)";
////                                                    gc.setSkillMajorNum(personStr);
////                                                    gc.setSignMajor(relation.getSignMajorFour());
////
////                                                } else {
////                                                    gc.setSignMajor(relation.getSignMajorFour());
////                                                }
////                                            }
////                                        } else {
////                                            // 4
////                                            String personStr = personNum + "(该专业人数不足)";
////                                            gc.setSkillMajorNum(personStr);
////                                        }
////                                    }
////                                }
////                            }
////                        }
////                    }
////                }
//
//                if (count >= 0) {
//                    if (personNum > 0) {
//                        gc.setSkillMajorNum(String.valueOf(personNum));
//                        SpecialtySignRelation relation = specialtySignRelationMapper.selectRelationByCode(gc.getSuppliesCode());
//
//                        if (StringUtils.isNotNull(relation)) {
//                            // 获取非空的专业列表
//                            List<String> majorList = new ArrayList<>();
//                            if (StringUtils.isNotNull(relation.getSignMajorOne())) {
//                                majorList.add(relation.getSignMajorOne());
//                            }
//                            if (StringUtils.isNotNull(relation.getSignMajorTwo())) {
//                                majorList.add(relation.getSignMajorTwo());
//                            }
//                            if (StringUtils.isNotNull(relation.getSignMajorThree())) {
//                                majorList.add(relation.getSignMajorThree());
//                            }
//                            if (StringUtils.isNotNull(relation.getSignMajorFour())) {
//                                majorList.add(relation.getSignMajorFour());
//                            }
//
//                            Boolean flag = true;
//
//                            // 遍历专业列表进行检查
//                            for (String major : majorList) {
//                                List<SpecialistInfo> specialistList = specialistInfoMapper.selectInfoByMajorName(major);
//                                if (specialistList.size() >= personNum) {
//                                    // 如果当前专业满足条件，更新
//                                    gc.setSignMajor(major);
//                                    flag = false;
//                                    break; // 找到满足条件的专业后退出
//                                }
//                            }
//
//                            if (flag) {
//                                // 如果没有满足条件的专业
//                                String personStr = personNum + "(该专业人数不足)";
//                                gc.setSkillMajorNum(personStr);
//                                // 选择最后一个专业作为备用
//                                if (!majorList.isEmpty()) {
//                                    // 选择最后一个非空专业
//                                    gc.setSignMajor(majorList.get(majorList.size() - 1));
//                                }
//                            }
//
//                        }
//                    }
//                }
//
//
//                // 异地人数
//                gc.setSkillOtherNum(skillOtherNum);
//                // 分组
//                gc.setSkillClass(keyName);
//                vos.add(gc);
//            }
//        }
//
//        // 将根据 signType 字段分组
//        Map<String, List<GCProgectVo>> groupedBySignType2 = vos.stream()
//                .collect(Collectors.groupingBy(GCProgectVo::getSignType));
//        // 将分组结果转换为
//        List<List<GCProgectVo>> busResult = new ArrayList<>(groupedBySignType2.values());
//
//        // 商务分组
//        // 创建 map 存储商务数据 标段类型 类型下计算出的总人数
//        Map<String, Integer> busTypeMap = new HashMap<>();
//
//        // 商务分组 获取商务家数/家次
//        String businessFamily = projectTask.getBusinessFamily();
//
//
//        // 计算出 每个类型所需 总人数
//        if (StringUtils.isNotEmpty(busResult)) {
//            for (List<GCProgectVo> list : busResult) {
//                int busTotalPerson = 0;
//                // 判断是家数还是家次
//                if (businessFamily.equals("家数")) {
//                    int totalFamilyNumber = list.stream()
//                            .mapToInt(GCProgectVo::getFamilyNumber)
//                            .sum();
//                    // 向上取整 Math.ceil() 商务人数
//                    double v = Double.valueOf(totalFamilyNumber) / projectTask.getBusinessSignNum();
//                    busTotalPerson = (int) Math.ceil(v);
//                } else {
//                    // 计算 familyNext 的总和
//                    int totalFamilyNext = list.stream()
//                            .mapToInt(GCProgectVo::getFamilyNext)
//                            .sum();
//                    double v = Double.valueOf(totalFamilyNext) / projectTask.getBusinessSignNum();
//                    busTotalPerson = (int) Math.ceil(v);
//                }
//                busTypeMap.put(list.get(0).getSignType(), busTotalPerson);
//            }
//        }
//
//
//        //  直接去存储数据
//        Map<String, List<GCProgectVo>> busTempMap = new HashMap<>();
//        for (int i = 0; i < busResult.size(); i++) {
//            // 获取 该 list 中的 标段类型
//            String signType = busResult.get(i).get(0).getSignType();
//            // 根据类型 获取 该类型所需总人数
//            Integer integer = busTypeMap.get(signType);
//
////            // 排序 标段类型 以及家数/家次
////            busResult.get(i).sort((vo1, vo2) -> {
////                // 按照 SignType 进行排序
////                int signTypeComparison = Comparator
////                        .comparing(GCProgectVo::getSignType, Comparator.nullsLast(Comparator.naturalOrder()))
////                        .compare(vo1, vo2);
////
////                if (signTypeComparison != 0) {
////                    return signTypeComparison;
////                }
////
////                // 判断 businessFamily 的值来决定后续排序
////                if ("家数".equals(businessFamily)) {
////                    return Comparator
////                            .comparing(GCProgectVo::getFamilyNumber, Comparator.nullsLast(Comparator.reverseOrder()))
////                            .compare(vo1, vo2);
////                } else {
////                    return Comparator
////                            .comparing(GCProgectVo::getFamilyNext, Comparator.nullsLast(Comparator.reverseOrder()))
////                            .compare(vo1, vo2);
////                }
////            });
//
//            // 获取 该类型 下小组数 以及人员数  商务组人数
//            List<Integer> classNumList =
//                    DealClassUtils.dealGcClassNum(integer, projectTask.getBusinessStart(), projectTask.getBusinessEnd());
//
//            // 判断 有几个小组
//            if (classNumList.size() == 1) {
//                // 小组人数为 1 直接赋值
//                // 存储数据
//                List<GCProgectVo> oneList = new ArrayList<>();
//                for (int j = 0; j < busResult.get(i).size(); j++) {
//                    busResult.get(i).get(j).setBossTotalNum(classNumList.get(0));
//                    oneList.add(busResult.get(i).get(j));
//                }
////                String className = "商务" + (busTempMap.size() + 1) + "组";
//                String className = "商务" + convertToChinese(busTempMap.size() + 1) + "组";
//                busTempMap.put(className, oneList);
//            } else if (classNumList.size() == 2) {
//                // 为两组 分出一组 即可， 剩下即为一组
//                List<GCProgectVo> oneList = new ArrayList<>();
//                List<GCProgectVo> twoList = new ArrayList<>();
//
//                // 该小组 预计总评标量  商务
//                Integer businessSignNum = projectTask.getBusinessSignNum() * classNumList.get(0);
//                // 当前次 的总和
//                int total = 0;
//                // 下一次数据总和
//                int nextValue = 0;
//                //  遍历 集合计算 列表中的评标量
//                for (int j = 0; j < busResult.get(i).size(); ) {
//                    // 判断是家数还是家次
//                    if (businessFamily.equals("家数")) {
//                        total += busResult.get(i).get(j).getFamilyNumber();
//                    } else {
//                        total += busResult.get(i).get(j).getFamilyNext();
//                    }
//
//                    if (total <= businessSignNum) {
//                        // 向map中添加数据值
//                        busResult.get(i).get(j).setBossTotalNum(classNumList.get(0));
//                        oneList.add(busResult.get(i).get(j));
//                        busResult.get(i).remove(j);
//                    } else {
//                        // 不满足 结束循环，避免其 无限循环
//                        break;
//                    }
//                    nextValue += 1;
//                    if (nextValue > busResult.get(i).size()) {
//                        // 数据标记，避免无限循环
//                        break;
//                    }
//                }
//
//                String className = "商务" + convertToChinese(busTempMap.size() + 1) + "组";
//                busTempMap.put(className, oneList);
//
//                for (int j = 0; j < busResult.get(i).size(); j++) {
//                    busResult.get(i).get(j).setBossTotalNum(classNumList.get(1));
//                    twoList.add(busResult.get(i).get(j));
//                }
//                String className2 = "商务" + convertToChinese(busTempMap.size() + 1) + "组";
//                busTempMap.put(className2, twoList);
//            } else if (classNumList.size() > 2) {
//                // 这里 是3组 及以上
//                // 循环小组
//                for (int j = 0; j < classNumList.size(); j++) {
//                    if (j == classNumList.size() - 1) {
//                        // 最后一次循环直接处理数据
//                        List<GCProgectVo> oneList = new ArrayList<>();
//                        if (!busResult.get(i).isEmpty()) {
//                            for (int k = 0; k < busResult.get(i).size(); k++) {
//                                busResult.get(i).get(k).setBossTotalNum(classNumList.get(j));
//                                oneList.add(busResult.get(i).get(k));
//                            }
//                            String className = "商务" + convertToChinese(busTempMap.size() + 1) + "组";
//                            busTempMap.put(className, oneList);
//                        }
//                    } else {
//                        List<GCProgectVo> oneList = new ArrayList<>();
//                        // 该小组 预计总评标量
//                        Integer skillSignNum = projectTask.getBusinessSignNum() * classNumList.get(j);
//                        int total = 0;
//                        // 下一次数据总和
//                        int nextValue = 0;
//                        //  遍历 集合计算 列表中的评标量
//                        for (int k = 0; k < busResult.get(i).size(); ) {
//                            // 判断是家数还是家次
//                            if (businessFamily.equals("家数")) {
//                                total += busResult.get(i).get(k).getFamilyNumber();
//                            } else {
//                                total += busResult.get(i).get(k).getFamilyNext();
//                            }
//
//                            if (total <= skillSignNum) {
//                                // 向map中添加数据值
//                                busResult.get(i).get(k).setBossTotalNum(classNumList.get(j));
//                                oneList.add(busResult.get(i).get(k));
//                                busResult.get(i).remove(k);
//                            } else {
//                                // 不满足 重新记录数据
//                                break;
//                            }
//
//                            nextValue += 1;
//                            if (nextValue > busResult.get(i).size()) {
//                                // 数据标记，避免无限循环
//                                break;
//                            }
//                        }
//                        // 获取组名
//                        String className = "商务" + convertToChinese(busTempMap.size() + 1) + "组";
//                        busTempMap.put(className, oneList);
//                    }
//                }
//            }
//        }
//
//        List<GCProgectVo> busVos = new ArrayList<>();
//        for (int i = 0; i < busTempMap.size(); i++) {
////            String keyName = "商务" + (i + 1) + "组";
//            String keyName = "商务" + convertToChinese(i + 1) + "组";
//            List<GCProgectVo> voList = busTempMap.get(keyName);
//            // 获取该小组 总人数
//            Integer bossTotalNum = voList.get(0).getBossTotalNum();
//            // 分配异地人数
//            //  （商务专家总人数+1）÷3（向上取整）
//            double v = Double.valueOf((bossTotalNum + 1)) / projectTask.getOtherSkill();
//            int bossOtherNum = (int) Math.ceil(v);
//            // 最后必须确保 本地 人数 大于 projectTask.getOtherLocal() (本地保留人数)
//            // 求 集合总数
//            int totalFamily = 0;
//            if (businessFamily.equals("家数")) {
//                totalFamily = voList.stream()
//                        .mapToInt(GCProgectVo::getFamilyNumber)
//                        .sum();
//            } else {
//                // 计算 familyNext 的总和
//                totalFamily = voList.stream()
//                        .mapToInt(GCProgectVo::getFamilyNext)
//                        .sum();
//            }
//
////            int count = 0;
//            int count = bossTotalNum;
//            for (GCProgectVo gc : voList) {
//                // 遍历集合 求占比
//                int temp = 0;
//                if (businessFamily.equals("家数")) {
//                    temp = gc.getFamilyNumber();
//                } else {
//                    // 计算 familyNext 的总和
//                    temp = gc.getFamilyNext();
//                }
//
//                // 计算占比
//                double proportion = (double) temp / totalFamily;
//                // 向上取整 Math.ceil()
//                int personNum = (int) Math.ceil(proportion * bossTotalNum);
//
//                if (count - personNum < 0) {
//                    personNum = count;  // 分配剩余的全部
//                }
//
//                // 更新count值
//                count -= personNum;
//
//                // 只在count大于0时进行赋值操作
//                if (count >= 0) {
//                    if (personNum > 0) {
//                        gc.setBossMajorNum(personNum);
//                    }
//                }
//                // 异地人数
//                gc.setBossOtherNum(bossOtherNum);
//                // 分组
//                gc.setBossClass(keyName);
//                busVos.add(gc);
//            }
//        }
//
//        // 数据库中添加数据
//        gcProgectMapper.insertBatchVo(busVos, taskId);
//    }

    // 逻辑 修改
    @Override
    public void processingGcDate(Integer taskId) {
        List<GCProgectVo> gcProgectVos = planInventoryMapper.selectSignName(taskId);
        if (StringUtils.isNotEmpty(gcProgectVos)) {
            // 首先 过滤掉 无用数据
            List<GCProgectVo> filteredGcProgectVos = gcProgectVos.stream()
                    .map(gc -> {
                        // 根据 分标名称 匹配出 epc2.0 标段类型
                        GCProgectVo epcTwoAndType = batchNeedMapper.selectEpcTwoAndType(taskId, gc.getSignName());
                        if (epcTwoAndType != null) {
                            gc.setEpcTwo(epcTwoAndType.getEpcTwo());
                            gc.setSignType(epcTwoAndType.getSignType());
                            return gc; // 返回有效数据
                        } else {
                            return null;
                        }
                    })
                    .filter(gc -> gc != null) // 过滤掉为 null 的条目
                    .collect(Collectors.toList()); // 收集结果

            // 更新原始列表
            gcProgectVos.clear();
            gcProgectVos.addAll(filteredGcProgectVos);

            for (GCProgectVo gc : gcProgectVos) {
                // 分标名称 找多少个部门 写到一起(进行部门的合并)
                List<String> comDepaList = planInventoryMapper.selectComDepa(taskId, gc.getSignName());
                // 处理 部分 合并
                gc.setComDepa(joinStrings(comDepaList));

                // 处理分包数量
                int num = batchNeedMapper.countKindNameNum(taskId, gc.getSignName());
                gc.setKindNameNum(num);

                // 家次 不去重
                int familyNext = recordCollectMapper.countFamilyNext(taskId, gc.getEpcTwo());
                gc.setFamilyNext(familyNext);

                // 家数 去重
                int familyNumber = recordCollectMapper.countFamilyNumber(taskId, gc.getEpcTwo());
                gc.setFamilyNumber(familyNumber);

                List<String> codeList = planInventoryMapper.selectGreaterThanSignMoney(taskId, gc.getSignName());
                // 如果没有找到金额大于30%的物料编码，则获取前三个物料编码
                if (codeList.isEmpty()) {
                    codeList = planInventoryMapper.selectThreeSignMoney(taskId, gc.getSignName());
                }

                // 物料编码不为空时，匹配专业
                if (!codeList.isEmpty()) {
                    List<String> tempStr = new ArrayList<>();
                    for (String code : codeList) {
                        SpecialtySignRelation relation = specialtySignRelationMapper.selectRelationByCode(code);
                        if (relation != null) {
                            // 按优先级匹配专家专业
                            if (StringUtils.isNotNull(relation.getSignMajorOne())) {
                                tempStr.add(relation.getSignMajorOne());
                            } else if (StringUtils.isNotNull(relation.getSignMajorTwo())) {
                                tempStr.add(relation.getSignMajorTwo());
                            } else if (StringUtils.isNotNull(relation.getSignMajorThree())) {
                                tempStr.add(relation.getSignMajorThree());
                            } else if (StringUtils.isNotNull(relation.getSignMajorFour())) {
                                tempStr.add(relation.getSignMajorFour());
                            }
                        }
                    }

                    // 拼接专业并去重
                    if (!tempStr.isEmpty()) {
                        Set<String> set = new LinkedHashSet<>(tempStr);
                        gc.setSignMajor(joinStrings(new ArrayList<>(set)));
                    }
                }
            }
        }
        // 先 排序
        gcProgectVos.sort(Comparator.comparing(GCProgectVo::getSignType, Comparator.nullsLast(Comparator.naturalOrder())));

        // 是否知道是那个类
        // 将根据 signType 字段分组
        Map<String, List<GCProgectVo>> groupedBySignType = gcProgectVos.stream()
                .collect(Collectors.groupingBy(GCProgectVo::getSignType));
        // 将分组结果转换为 List<List<GCProgectVo>>
        List<List<GCProgectVo>> result = new ArrayList<>(groupedBySignType.values());

        // 获取 任务公式 信息
        ProjectTask projectTask = projectTaskMapper.selectById(taskId);
        // 技术评标量(家数/家次)
        String skillFamily = projectTask.getSkillFamily();

        // 技术分组
        // 创建 map 存储数据 标段类型 类型下计算出的总人数
        Map<String, Integer> typeMap = new HashMap<>();

        // 计算出 每个类型所需 总人数
        if (StringUtils.isNotEmpty(result)) {
            for (List<GCProgectVo> list : result) {
                int skillTotalPerson = 0;
                // 判断是家数还是家次
                if (skillFamily.equals("家数")) {
                    int totalFamilyNumber = list.stream()
                            .mapToInt(GCProgectVo::getFamilyNumber)
                            .sum();
                    // 向上取整 Math.ceil()
                    double v = Double.valueOf(totalFamilyNumber) / projectTask.getSkillSignNum();
                    skillTotalPerson = (int) Math.ceil(v);
                } else {
                    // 计算 familyNext 的总和
                    int totalFamilyNext = list.stream()
                            .mapToInt(GCProgectVo::getFamilyNext)
                            .sum();
                    double v = Double.valueOf(totalFamilyNext) / projectTask.getSkillSignNum();
                    skillTotalPerson = (int) Math.ceil(v);
                }
                typeMap.put(list.get(0).getSignType(), skillTotalPerson);
            }
        }


        // 直接去存储数据
        Map<String, List<GCProgectVo>> tempMap = new HashMap<>();
        for (int i = 0; i < result.size(); i++) {
            // 存储有几列数据
            List<Integer> recordNum = new ArrayList<>();
            // 获取 该 list 中的 标段类型
            String signType = result.get(i).get(0).getSignType();
            // 根据类型 获取 该类型所需总人数
            Integer integer = typeMap.get(signType);

            // 获取 该类型 下小组数 以及人员数
            List<Integer> classNumList =
                    DealClassUtils.dealGcClassNum(integer, projectTask.getSkillStart(), projectTask.getSkillEnd());

            // 判断 有几个小组
            if (classNumList.size() == 1) {
                // 小组人数为 1 直接赋值
                // 存储数据
                List<GCProgectVo> oneList = new ArrayList<>();
                for (int j = 0; j < result.get(i).size(); j++) {
                    result.get(i).get(j).setSkillTotalNum(classNumList.get(0));
                    oneList.add(result.get(i).get(j));
                }
                String className = "技术" + convertToChinese(tempMap.size() + 1) + "组";
                if (!oneList.isEmpty()) {
                    tempMap.put(className, oneList);
                }
            } else if (classNumList.size() == 2) {
                // 为两组 分出一组 即可， 剩下即为一组
                List<GCProgectVo> oneList = new ArrayList<>();
                List<GCProgectVo> twoList = new ArrayList<>();

                // 该小组 预计总评标量
                Integer skillSignNum = projectTask.getSkillSignNum() * classNumList.get(0);
                // 当前次 的总和
                int total = 0;
                // 下一次数据总和
                int nextValue = 0;
                //  遍历 集合计算 列表中的评标量
                for (int j = 0; j < result.get(i).size(); ) {
                    // 判断是家数还是家次
                    if (skillFamily.equals("家数")) {
                        total += result.get(i).get(j).getFamilyNumber();
                    } else {
                        total += result.get(i).get(j).getFamilyNext();
                    }

                    if (total <= skillSignNum) {
                        // 向map中添加数据值
                        result.get(i).get(j).setSkillTotalNum(classNumList.get(0));
                        oneList.add(result.get(i).get(j));
                        result.get(i).remove(j);
                    } else {
                        // 不满足 结束循环，避免其 无限循环
                        break;
                    }
                    nextValue += 1;
                    if (nextValue > result.get(i).size()) {
                        // 数据标记，避免无限循环
                        break;
                    }
                }

                String className = "技术" + convertToChinese(tempMap.size() + 1) + "组";
                if (!oneList.isEmpty()) {
                    tempMap.put(className, oneList);
                }

                for (int j = 0; j < result.get(i).size(); j++) {
                    result.get(i).get(j).setSkillTotalNum(classNumList.get(1));
                    twoList.add(result.get(i).get(j));
                }
                String className2 = "技术" + convertToChinese(tempMap.size() + 1) + "组";
                if (!twoList.isEmpty()) {
                    tempMap.put(className2, twoList);
                }
            } else if (classNumList.size() > 2) {
                // 这里 是3组 及以上
                // 循环小组
                for (int j = 0; j < classNumList.size(); j++) {
                    if (j == classNumList.size() - 1) {
                        // 最后一次循环直接处理数据
                        List<GCProgectVo> oneList = new ArrayList<>();
                        if (!result.get(i).isEmpty()) {
                            for (int k = 0; k < result.get(i).size(); k++) {
                                result.get(i).get(k).setSkillTotalNum(classNumList.get(j));
                                oneList.add(result.get(i).get(k));
                            }
                            String className = "技术" + convertToChinese(tempMap.size() + 1) + "组";
                            if (!oneList.isEmpty()) {
                                tempMap.put(className, oneList);
                            }
                        }
                    } else {
                        List<GCProgectVo> oneList = new ArrayList<>();
                        // 该小组 预计总评标量
                        Integer skillSignNum = projectTask.getSkillSignNum() * classNumList.get(j);
                        int total = 0;
                        // 下一次数据总和
                        int nextValue = 0;
                        //  遍历 集合计算 列表中的评标量
                        for (int k = 0; k < result.get(i).size(); ) {
                            // 判断是家数还是家次
                            if (skillFamily.equals("家数")) {
                                total += result.get(i).get(k).getFamilyNumber();
                            } else {
                                total += result.get(i).get(k).getFamilyNext();
                            }

                            if (total <= skillSignNum) {
                                // 向map中添加数据值
                                result.get(i).get(k).setSkillTotalNum(classNumList.get(j));
                                oneList.add(result.get(i).get(k));
                                result.get(i).remove(k);
                            } else {
                                // 不满足 重新记录数据
                                break;
                            }

                            nextValue += 1;
                            if (nextValue > result.get(i).size()) {
                                // 数据标记，避免无限循环
                                break;
                            }
                        }
                        // 获取组名
                        String className = "技术" + convertToChinese(tempMap.size() + 1) + "组";
                        if (!oneList.isEmpty()) {
                            tempMap.put(className, oneList);
                        }
                    }
                }
            }
        }

        List<GCProgectVo> vos = new ArrayList<>();
        for (int i = 0; i < tempMap.size(); i++) {
            String keyName = "技术" + convertToChinese(i + 1) + "组";
            List<GCProgectVo> voList = tempMap.get(keyName);
            // 获取该小组 总人数
            Integer skillTotalNum = voList.get(0).getSkillTotalNum();
            // 分配异地人数
            //  （技术专家总人数+1）÷3（向上取整）
            double v = Double.valueOf((skillTotalNum + 1)) / projectTask.getOtherSkill();
            int skillOtherNum = (int) Math.ceil(v);
            // 最后必须确保 本地 人数 大于 projectTask.getOtherLocal() (本地保留人数)
            // 求 集合总数
            int totalFamily = 0;
            if (skillFamily.equals("家数")) {
                totalFamily = voList.stream()
                        .mapToInt(GCProgectVo::getFamilyNumber)
                        .sum();
            } else {
                // 计算 familyNext 的总和
                totalFamily = voList.stream()
                        .mapToInt(GCProgectVo::getFamilyNext)
                        .sum();
            }

            // 根据 gc.getSignMajor() 排序，处理 null 值
//            Collections.sort(voList, Comparator.comparing(GCProgectVo::getSignMajor, Comparator.nullsFirst(Comparator.naturalOrder())));

            // 使用 Map 存储每个 技术专家专业 对应的 FamilyNumber 总和
            Map<String, Integer> sumMap = new HashMap<>();
            for (GCProgectVo gc : voList) {
                String signMajor = gc.getSignMajor();
                int temp = 0;
                if (skillFamily.equals("家数")) {
                    temp = gc.getFamilyNumber();
                } else {
                    temp = gc.getFamilyNext();
                }

                // 如果 SignMajor 已经在 Map 中，则累加 家数/家次
                if (signMajor != null) {
                    if (sumMap.containsKey(signMajor)) {
                        sumMap.put(signMajor, sumMap.get(signMajor) + temp);
                        // 相同专业 只 保留一个
//                        gc.setSignMajor(null);
                    } else {
                        // 否则，将 SignMajor 和 FamilyNumber 放入 Map
                        sumMap.put(signMajor, temp);
                    }
                }
            }

            int count = skillTotalNum;
            // 将 Map 转换为 List，并根据 Integer 值进行排序
            List<Map.Entry<String, Integer>> sortedList = new ArrayList<>(sumMap.entrySet());
            sortedList.sort((entry1, entry2) -> entry2.getValue().compareTo(entry1.getValue()));

            Map<String, Integer> personMap = new HashMap<>();
            for (Map.Entry<String, Integer> entry : sortedList) {
                // 计算占比
                double proportion = (double) entry.getValue() / totalFamily;
                // 向上取整 Math.ceil()
                int personNum = (int) Math.ceil(proportion * skillTotalNum);
                if (count - personNum < 0) {
                    // 分配剩余的全部
                    personNum = count;
                }
                count -= personNum;
                if (count >= 0) {
                    if (personNum > 0) {
                        personMap.put(entry.getKey(), personNum);
                    }
                }
            }

            Set<String> assignedMajors = new HashSet<>();
            for (Map.Entry<String, Integer> entry : personMap.entrySet()) {
                // 进行专业 对比
                for (GCProgectVo gc : voList) {
                    if (gc.getSignMajor() == null) {
                        continue;
                    }

                    if (assignedMajors.contains(gc.getSignMajor())) {
                        continue;
                    }

                    if (gc.getSignMajor().equals(entry.getKey())) {
                        gc.setSkillMajorNum(String.valueOf(entry.getValue()));
                        // 将该专业加入已赋值集合
                        assignedMajors.add(gc.getSignMajor());
                    }
                }
            }

            for (GCProgectVo gc : voList) {
                // 异地人数
                gc.setSkillOtherNum(skillOtherNum);
                // 分组
                gc.setSkillClass(keyName);
                vos.add(gc);
            }
        }

        // 将根据 signType 字段分组
        Map<String, List<GCProgectVo>> groupedBySignType2 = vos.stream()
                .collect(Collectors.groupingBy(GCProgectVo::getSignType));
        // 将分组结果转换为
        List<List<GCProgectVo>> busResult = new ArrayList<>(groupedBySignType2.values());

        // 商务分组
        // 创建 map 存储商务数据 标段类型 类型下计算出的总人数
        Map<String, Integer> busTypeMap = new HashMap<>();

        // 商务分组 获取商务家数/家次
        String businessFamily = projectTask.getBusinessFamily();

        Map<String, Map<String, List<GCProgectVo>>> skillMap = new HashMap<>();
        for (List<GCProgectVo> list : busResult) {
            // 获取 标段 类型
            String signType = list.get(0).getSignType();
            Map<String, List<GCProgectVo>> gropupBySkill = list.stream()
                    .collect(Collectors.groupingBy(GCProgectVo::getSkillClass));
            skillMap.put(signType, gropupBySkill);
        }

        Integer start = projectTask.getBusinessStart();
        Integer end = projectTask.getBusinessEnd();
        List<List<Integer>> intList = new ArrayList<>();
        int indexFlag = 1;
        for (Map.Entry<String, Map<String, List<GCProgectVo>>> entry : skillMap.entrySet()) {
            List<Integer> list = new ArrayList<>();
            Map<String, List<GCProgectVo>> skillClassMap = entry.getValue();
            for (int i = 0; i < skillClassMap.size(); i++) {
                String keyName = "技术" + convertToChinese(indexFlag) + "组";
                indexFlag += 1;
                List<GCProgectVo> voList = tempMap.get(keyName);
                if (voList.isEmpty()) {
                    continue;
                }
                // 计算 商务 组 总人数
                int busTotalPerson = 0;
                // 判断是家数还是家次
                if (businessFamily.equals("家数")) {
                    int totalFamilyNumber = voList.stream()
                            .mapToInt(GCProgectVo::getFamilyNumber)
                            .sum();
                    // 向上取整 Math.ceil() 商务人数
                    double v = Double.valueOf(totalFamilyNumber) / projectTask.getBusinessSignNum();
                    busTotalPerson = (int) Math.ceil(v);
                } else {
                    // 计算 familyNext 的总和
                    int totalFamilyNext = voList.stream()
                            .mapToInt(GCProgectVo::getFamilyNext)
                            .sum();
                    double v = Double.valueOf(totalFamilyNext) / projectTask.getBusinessSignNum();
                    busTotalPerson = (int) Math.ceil(v);
                }
                if (busTotalPerson > end) {
                    throw new CommonException(CommonConstants.ERROR, "超出商务组最大组人数");
                }
                list.add(busTotalPerson);
            }
            intList.add(list);
        }

        // 下标集合
        List<List<Integer>> flagList = countPersonFlag(end, intList);
        // 累加集合
        List<List<Integer>> sumTest = countSumFlag(end, intList);
        // 自动向下取整
        Integer num = start / 2;
        for (int i = 0; i < sumTest.size(); i++) {
            List<Integer> currSum = sumTest.get(i);
            List<Integer> currResult = flagList.get(i);
            for (int j = 0; j < currSum.size(); j++) {
                Integer temp = currSum.get(j);

                if (temp <= num) {
                    if (j == 0) {
                        if (j + 1 >= currSum.size()) {
                            currSum.set(j, start);
                        } else {
                            currResult.set(j + 1, currResult.get(j) + 1);
                            currResult.remove(j);
                            currSum.remove(j);
                            j--; // 因为删除了元素，需要减少j
                        }
                    } else {
                        currResult.set(j - 1, currResult.get(j - 1) + 1);
                        currResult.remove(j);
                        currSum.remove(j);
                        j--; // 因为删除了元素，需要减少j
                    }
                } else if (temp < start) {
                    currSum.set(j, start);
                } else {
                    boolean oddFlag = isOdd(temp);
                    if (!oddFlag) {
                        currSum.set(j, temp + 1);
                    }
                }
            }
        }

        // 按照 技术 分组进行 标记
        //  直接去存储数据
        Map<String, List<GCProgectVo>> busTempMap = new HashMap<>();
        Map<String, List<GCProgectVo>> classMap = vos.stream()
                .collect(Collectors.groupingBy(GCProgectVo::getSkillClass));
        int flag = 0;
        for (int i = 0; i < flagList.size(); i++) {
            List<Integer> currResult = flagList.get(i);
            List<Integer> currSum = sumTest.get(i);
            int prevIndex = 0;

            for (int j = 0; j < currResult.size(); j++) {
                int index = currResult.get(j);
                Integer totalNum = currSum.get(j);
                List<GCProgectVo> arrayList = new ArrayList<>();
                for (int k = prevIndex + 1; k <= index; k++) {
                    flag++;
                    String keyName = "技术" + convertToChinese(flag) + "组";
                    List<GCProgectVo> list = classMap.getOrDefault(keyName, Collections.emptyList());
                    // 填入 商务 分组 以及数据
                    for (GCProgectVo vo : list) {
                        // 添加商务组 总人数
                        vo.setBossTotalNum(totalNum);
                    }
                    arrayList.addAll(list);
                }
                prevIndex = index;
                String name = "商务" + convertToChinese(busTempMap.size() + 1) + "组";
                busTempMap.put(name, arrayList);
            }
        }

        List<GCProgectVo> busVos = new ArrayList<>();
        for (int i = 0; i < busTempMap.size(); i++) {
            String keyName = "商务" + convertToChinese(i + 1) + "组";
            List<GCProgectVo> voList = busTempMap.get(keyName);
            // 获取该小组 总人数
            Integer bossTotalNum = voList.get(0).getBossTotalNum();
            // 获取 标段类型
            String signType = voList.get(0).getSignType();
            // 分配异地人数
            //  （商务专家总人数+1）÷3（向上取整）
            double v = Double.valueOf((bossTotalNum + 1)) / projectTask.getOtherSkill();
            int bossOtherNum = (int) Math.ceil(v);

            if (signType.contains("施工")) {
                if (voList.size() >= 3) {
                    setMajors(voList, bossTotalNum);
                } else {
                    while (voList.size() < 3) {
                        GCProgectVo vo = new GCProgectVo();
                        vo.setSkillClass(voList.get(0).getSkillClass());
                        voList.add(vo);
                    }
                    setMajors(voList, bossTotalNum);
                }
            } else {
                for (int j = 0; j < voList.size(); j++) {
                    if (j == 0) {
                        voList.get(j).setBossSignMajor("商务综合");
                        voList.get(j).setBossMajorNum(bossTotalNum);
                    }
                }
            }

            for (GCProgectVo gc : voList) {
                // 异地人数
                gc.setBossOtherNum(bossOtherNum);
                // 分组
                gc.setBossClass(keyName);
                busVos.add(gc);
            }
        }

        // 数据库中添加数据
        gcProgectMapper.insertBatchVo(busVos, taskId);
    }

    public static boolean isOdd(int number) {
        return number % 2 != 0;
    }

    public static List<List<Integer>> countPersonFlag(Integer end, List<List<Integer>> intList) {
        List<List<Integer>> result = new ArrayList<>();

        for (List<Integer> list : intList) {
            Integer sum = 0;
            int indexFlag = 1;
            List<Integer> indices = new ArrayList<>();
            for (int i = 0; i < list.size(); i++) {
                sum += list.get(i);
                if (sum >= end || (i < list.size() - 1 && sum + list.get(i + 1) > end)) {
                    // 记录当前索引 + 1
                    indices.add(i + 1);
                    // 将 sum 归零
                    sum = 0;
                }
            }
            if (sum > 0) {
                // 如果循环结束时 sum 还有值，记录最后一个索引
                indices.add(list.size());
            }
            result.add(indices);
        }
        return result;
    }


    public static List<List<Integer>> countSumFlag(Integer end, List<List<Integer>> intList) {
        List<List<Integer>> valuesResult = new ArrayList<>();
        for (List<Integer> list : intList) {
            Integer sum = 0;
            List<Integer> values = new ArrayList<>();
            for (int i = 0; i < list.size(); i++) {
                sum += list.get(i);
                if (sum >= end || (i < list.size() - 1 && sum + list.get(i + 1) > end)) {
                    // 记录当前的累加值
                    values.add(sum);
                    sum = 0;
                }
            }
            if (sum > 0) {
                // 记录最后一个累加值
                values.add(sum);
            }
            valuesResult.add(values);
        }
        return valuesResult;
    }

    @Override
    public List<GCProgectVo> createGCProgect(Integer taskId) {
        List<GCProgectVo> list = gcProgectMapper.createGCProgect(taskId);
        int countIndex = 1;
        for (GCProgectVo l : list) {
            l.setSerialNumber(countIndex);
            countIndex += 1;
        }
        return list;
    }

    @Override
    public int deleteByTaskId(Integer taskId) {
        return gcProgectMapper.deleteByTaskId(taskId);
    }

    @Override
    public Page<GcProgect> pageGcProgect(BatchNeedParam param) {
        Integer offset = (param.getPageNum() - 1) * param.getPageSize();
        param.setOffset(offset);

        // 分页查询
        Page<GcProgect> page = new Page<>(param.getPageNum(), param.getPageSize());
        List<GcProgect> list = gcProgectMapper.selectGcProgectByPage(param);

        // 页码
        page.setCurrent(param.getPageNum());
        page.setSize(param.getPageSize());

        // 总记录数
        Long aLong = gcProgectMapper.pageGcProgectCount(param);
        page.setTotal(aLong);
        page.setRecords(list);

        return page;
    }

    @Override
    public int updateGcProgect(GcProgect gcProgect) {
        return gcProgectMapper.updateGcProgect(gcProgect);
    }

    private void setMajors(List<GCProgectVo> voList, Integer totalNum) {
        for (int j = 0; j < voList.size(); j++) {
            if (j == 0) {
                voList.get(j).setBossSignMajor("常规变电电气技术经济");
                voList.get(j).setBossMajorNum(1);
            } else if (j == 1) {
                voList.get(j).setBossSignMajor("常规输电线路技术经济");
                voList.get(j).setBossMajorNum(1);
            } else if (j == 2) {
                voList.get(j).setBossMajorNum(totalNum - 2);
                voList.get(j).setBossSignMajor("商务综合");
            }
        }
    }

    public static void allocateOtherNum(List<GCProgectVo> gcProgectVos, int total, String family) {
        // 判断 是家数还是 家次
        int totalStuNum = 0;
        if (family.equals("家数")) {
            totalStuNum = gcProgectVos.stream().mapToInt(GCProgectVo::getFamilyNumber).sum();
        } else {
            totalStuNum = gcProgectVos.stream().mapToInt(GCProgectVo::getFamilyNext).sum();
        }

        Map<String, GCProgectVo> nameToTestMap = new HashMap<>();
        for (GCProgectVo test : gcProgectVos) {
            nameToTestMap.putIfAbsent(test.getSignMajor(), test);
        }

        for (GCProgectVo test : nameToTestMap.values()) {
            double ratio = 0.0;
            if (family.equals("家数")) {
                ratio = (double) test.getFamilyNumber() / totalStuNum;
            } else {
                ratio = (double) test.getFamilyNext() / totalStuNum;
            }

            int allocatedValue = (int) Math.round(ratio * total);
            test.setSkillMajorNum(String.valueOf(allocatedValue));
        }


//        // 计算总的 stuNum
//        int totalStuNum =
//
//        // 创建一个 map 存储每个 name 对应的 Test 对象
//        Map<String, Test> nameToTestMap = new HashMap<>();
//        for (Test test : tests) {
//            nameToTestMap.putIfAbsent(test.getName(), test);
//        }
//
//        // 计算每个 name 的 total 分配
//        for (Test test : nameToTestMap.values()) {
//            double ratio = (double) test.getStuNum() / totalStuNum;
//            int allocatedValue = (int) Math.round(ratio * total);
//            test.setOtherNum(allocatedValue);
//        }
    }

    // 处理部门人数
    public static Map<String, List<Integer>> processDeptMap(Map<String, Integer> deptMap) {
        // 初始化空的 mapList
        Map<String, List<Integer>> mapList = new HashMap<>();

        int totalFlag = 0;

        // 遍历 deptMap，动态处理每个部门
        for (Map.Entry<String, Integer> entry : deptMap.entrySet()) {
            String deptName = entry.getKey();
            Integer deptValue = entry.getValue();

            // 创建对应的List
            List<Integer> deptList = new ArrayList<>();

            // 计算整除结果
            int quotient = deptValue / 13;
            if (quotient > 0) {
                for (int i = 0; i < quotient; i++) {
                    deptList.add(13);
                }
            }

            int remainder = deptValue % 13;
            int flag = 0;

            boolean isValidDept = isValidRemainder(remainder);
            if (isValidDept) {
                deptList.add(remainder);
            } else {
                if (remainder > 5) {
                    int[] ints = findTwoOddNumbers(remainder);
                    for (int i : ints) {
                        deptList.add(i);
                    }
                    flag = (ints.length == 1) ? 1 : 0;
                } else {
                    flag = remainder;
                }
            }

            mapList.put(deptName, deptList);

            totalFlag += flag;
        }

        if (totalFlag > 0) {
            for (Map.Entry<String, List<Integer>> entry : mapList.entrySet()) {
                String key = entry.getKey();
                List<Integer> list = entry.getValue();
                if (!list.isEmpty()) {
                    int index = 0;
                    for (Integer i : list) {
                        if (i < 13 && i + totalFlag < 13) {
                            boolean validJiShu = isValidJiShu(i + totalFlag);
                            if (validJiShu) {
                                list.set(index, i + totalFlag);
                            } else {
                                list.set(index, i + totalFlag + 1);
                            }
                            totalFlag = 0;
                            break;
                        } else if (i + totalFlag >= 13) {
                            list.set(index, 13);
                            totalFlag += i + totalFlag - 13;
                        }
                        index += 1;
                    }
                }
            }
        }
        return mapList;
    }

    private static boolean isValidRemainder(int remainder) {
        return remainder >= 5 && remainder <= 13 && remainder % 2 != 0;
    }

    private static boolean isValidJiShu(int value) {
        return value % 2 != 0;
    }

    private static int[] findTwoOddNumbers(int input) {
        int[] oddNumbers = {5, 7, 9, 11, 13};
        for (int i = 0; i < oddNumbers.length; i++) {
            for (int j = i; j < oddNumbers.length; j++) {
                if (oddNumbers[i] + oddNumbers[j] == input) {
                    return new int[]{oddNumbers[i], oddNumbers[j]};
                }
            }
        }
        return new int[]{input - 1};
    }


    /**
     * 根据 字符串 列表 拼接字符串
     *
     * @param stringList 字符串 列表
     * @return
     */
    public static String joinStrings(List<String> stringList) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < stringList.size(); i++) {
            sb.append(stringList.get(i));
            if (i < stringList.size() - 1) {
                sb.append(",");
            }
        }
        return sb.toString();
    }

    // 传入 数字 返回 其中文样式
    public static String convertToChinese(int number) {
        if (number < 1 || number > 99) {
            throw new IllegalArgumentException("支持的范围是 1 到 99");
        }

        String[] chineseDigits = {"零", "一", "二", "三", "四", "五", "六", "七", "八", "九"};

        int tens = number / 10;
        int units = number % 10;

        StringBuilder result = new StringBuilder();

        if (tens > 0) {
            result.append(chineseDigits[tens]);
            result.append("十");
        }

        if (units > 0 || tens == 0) { // 处理个位是0的情况
            result.append(chineseDigits[units]);
        }

        // 如果只有十位数而个位数是0，不要显示个位的零
        return result.toString().replaceAll("^一十", "十"); // 将 "一十" 转换为 "十"
    }
}

